package com.csii.security.authorize;

import com.csii.autopoi.util.ApplicationContextUtil;
import com.csii.security.CustomUserDetailsService;
import com.csii.security.store.ColaTokenEnhancer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.builders.JdbcClientDetailsServiceBuilder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 鉴权服务配置配
 *
 * @author daixiaochun@csiisz.com
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter
{

    @Autowired
    public PasswordEncoder passwordEncoder;

    @Autowired
    private CustomUserDetailsService colaUserDetailsService;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private TokenEnhancer tokenEnhancer;
/**
      @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;*/

    /**
     * 配置授权（authorization）以及令牌（token）的访问端点和令牌服务(token services)
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception
    {
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> enhancerList = new ArrayList<>();
        enhancerList.add(tokenEnhancer());
        enhancerChain.setTokenEnhancers(enhancerList);
        endpoints.tokenStore(tokenStore)
                .tokenEnhancer(enhancerChain)
                //刷新令牌的时候需要
                .userDetailsService(colaUserDetailsService)
                .authenticationManager(authenticationManager);

    }

    /**
     * 配置客户端，目前从DB中读取
     *
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception
    {
        JdbcClientDetailsServiceBuilder jcsb = clients.jdbc(dataSource);
        jcsb.passwordEncoder(passwordEncoder);
    }

    /**
     * 配置令牌端点(Token Endpoint)的安全约束
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception
    {
        //允许表单认证
        security.allowFormAuthenticationForClients()
                //客户端校验Token需要用户认证
                .checkTokenAccess("isAuthenticated()")
                //客户端获取jwt秘钥需要用户认证
                .tokenKeyAccess("permitAll()");
    }

    @Bean
    public TokenEnhancer tokenEnhancer()
    {
        return new ColaTokenEnhancer();
    }
}
